---
title: groovy 语法
---
Groovy 是一种基于 JVM 的动态语言，它的语法和 Java 类似，最终也是要编译 .class 在 JVM 上运行。Groovy 完全兼容 Java 并且在此基础上添加了很多动态类型和灵活的特性，比如闭包，支持 DSL（领域特定语言），是一门非常灵活的动态脚本语言。

## 变量
Groovy 中用 def 关键字来定义变量，可以不指定变量的类型，默认访问修饰符是 public。

```groovy
package pub.wkq
/**
 * 默认是 public*/
class Test {
    static void main(String[] args) {
        println "Groovy Hello World!"
        def a = 1
        def int b = 1
        def c = "hello world"
        println "c = $c + $a"
    }
}
```
## 方法
方法使用返回类型或def关键字

```groovy
def add(int a,int b){
    println a+b
}
int minus(a,b){
    println a-b
}

add(23,25)
minus(22,11)
```
如果不使用 return ，方法的返回值为最后一行代码的执行结果。
```groovy
def add(int a, int b) {
    println a + b + minus(a, b)
}

int minus(a, b) {
    a - b
}

add(23, 25)
minus(22, 11)
```
groovy 中有很多可以省略的地方：
1. 语句后面的分号可以省略
2. 方法的括号可以省略
3. 参数类型可以省略
4. return 可以省略掉

## 类
Groovy 类非常类似于 Java 类
```groovy
package pub.wkq
/**
 * 属性有 name，age = 10
 */
class Person {
    String  name
    Integer age = 10
    def increaseAge(Integer years){
        this.age += years
    }
}


println("----------------------")
def p = new Person()
p.increaseAge(23)
println("age:" + p.getAge())
```
Groovy 类与 Java 类有以下的区别：
1. 默认类的修饰符为 public。
2. 没有可见修饰符的字段会自动生成对应的 setter 和 getter 方法。
3. 类不需要与它的源文件有相同的名称，但还是建议采用相同的名称

## 语句
### 断言
Groovy 断言与 Java 断言不同。它一直处于开启状态，是进行单元测试的首选方式。
```groovy
assert 1+2==6
```
当断言条件为 false 时，程序会抛出异常，不在执行下面的代码，从输出可以很清楚的看到发生错误的地方。

### for循环
Groovy 支持 Java 的 for(int i = 0;i `<` N; i++) 和 for(int i : array) 形式的循环语句，另外还支持 for in loop 形式，支持遍历范围、列表、Map、数组和字符串等多种类型。
```groovy
//遍历范围
def x = 0
for (i in 0..3) {
    x += i
}
assert x == 6
//遍历列表
x = 0
for (i in [0, 1, 2, 3]) {
    x += i
}
assert x == 6
//遍历 map 中的值
def map = ['a': 1, 'b': 2, 'c': 3]
x = 0
for (v in map.values()) {
    x += v
}
assert x == 6

```
### switch 语句
Groovy 中的 Switch 语句不仅兼容 java 代码，还可以处理更多类型的 case 表达式。
```groovy

def y = 16
def result = ""
switch (y) {
    case "ok":
        result = "found ok"
    case [1, 2, 4, 'list']:
        result = 'list'
        break
    case 10..19:
        result = 'range'
        break
    case Integer:
        result = 'integer'
        break
    default:
        result = 'default'
}
println(result)
```
case 表达式可以是字符串、列表、范围、Integer 等等。
## 数据类型
Groovy 中的数据类型主要有：
1. Java 中的基本数据类型
2. Groovy 中的容器类
3. 闭包
### 字符串
Groovy 中有两种字符串类型，普通字符串 String 和插值字符串 （groovy.lang.GString）。单引号字符串不支持插值。双引号字符串支持插值，占位符表达式为 `${}` 或者以 `$` 为前缀.
```groovy
def name = 'Android进阶'
println "hello ${name}"
println "hello $name"
```
三引号字符串可以保留文本的换行和索引格式，不支持插值。
### List
Groovy 没有定义自己的集合类，它在Java集合类的基础上进行了增强和简化，Groovy 的 List 对应 Java 的 List 接口，默认实现类为 ArrayList，它的创建方式有以下几种：
```groovy
def list = [1, 2, 3]
def list2 = new ArrayList()
def list3 = []
```
可以使用 as 操作符来显式指定  List 的实现类为 java.util.LinkedList。
```groovy
def list = [1, 2, 3] as LinkedList
```
获取元素同样要比Java 简单，可以使用下标或者 get 方法。
```groovy
def list = [1, 2, 3]
println list[0]
println list.get(0)
```
### Map
创建 Map 同样是使用 [],需要同时指定键和值，默认的实现类为 java.util.LinkedHashMap。
```groovy
def name = ['a': '魏无羡', 'b': '杨影风', 'c': '张无忌']
assert name['a'] == '魏无羡'
assert name.get('b') == '杨影风'
```
### 闭包
Groovy 中的闭包是一个开放的、匿名的，可以接受参数的代码块。
#### 定义闭包
闭包的定义使用 {}，参数列表使用 ->，参数列表可以省略。

```groovy
//闭包
//定义闭包
def running = { println it }
//调用闭包
running(1)


def c = { String a, String b -> println a + b }
c('hello', 'world')
```
#### 闭包作为参数
闭包可以作为方法的参数，也可以作为方法的返回值。
```groovy
//闭包作为参数
def running = { println it }
def run(closure) {
    closure(1)
}
run(running)
```
#### 闭包作为返回值
```groovy
//闭包作为返回值
def running() {
    def c = { println it }
    return c
}
def r = running()
r(1)
```

